package hephaestus.security;

import hephaestus.security.exceptions.HephaestusCertificateCreationException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * This class encapsulates a X509 Public Key Certificate
 * 
 * @author João Dias Amaro
 */
public class HephaestusCertificate 
{
	private X509Certificate certificate;
	
	/**
	 * Builds a X509 PK Certificate from a given Input Stream
	 * 
	 * @param certificateStream
	 * @throws HephaestusCertificateCreationException
	 */
	public HephaestusCertificate(InputStream certificateStream) throws HephaestusCertificateCreationException
	{
		this.buildCertificate(certificateStream);
	}
	
	public HephaestusCertificate(File certificateFile) throws HephaestusCertificateCreationException
	{
		if(certificateFile == null || !certificateFile.exists() || !certificateFile.isFile())
		{
			throw new HephaestusCertificateCreationException("The certificate source must be correctly defined before creation");
		}
		
		if(!certificateFile.canRead()) throw new HephaestusCertificateCreationException("The certificate file can't be read");
		
		try 
		{
			this.buildCertificate(new FileInputStream(certificateFile));
		}
		catch(FileNotFoundException e)
		{
			throw new HephaestusCertificateCreationException("", e);
		}
	}
	
	private void buildCertificate(InputStream certStream) throws HephaestusCertificateCreationException
	{
		if(certStream == null) 
		{
			throw new HephaestusCertificateCreationException("The certificate source must be defined before creation", new NullPointerException("stream is null"));
		}
		
		try 
		{
			if(certStream.available() <= 0) throw new HephaestusCertificateCreationException("The certificate source is empty");
			this.certificate = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certStream);
		} 
		catch(CertificateException e)
		{
			throw new HephaestusCertificateCreationException("The certificate type is invalid", e);
		} 
		catch(IOException e)
		{
			throw new HephaestusCertificateCreationException("There was an error while building the certificate", e);
		}
	}
	
	public PublicKey getPublickKey()
	{
		return this.certificate.getPublicKey();
	}
}
